
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传进度监控</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <style>
        .progress-bar {
            transition: width 0.3s ease-in-out;
        }
        .fade-in {
            animation: fadeIn 0.5s ease-in;
        }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
    </style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-8">
    <!-- 头部导航 -->
    <header class="bg-white rounded-lg shadow-sm p-6 mb-6 fade-in">
        <h1 class="text-3xl font-bold text-gray-800">
            <i class="fas fa-file-upload mr-3 text-blue-500"></i>
            文件上传进度监控系统
        </h1>
        <p class="text-gray-600 mt-2">基于WebSocket的实时文件上传进度展示</p>
    </header>

    <!-- 主功能区域 -->
    <main class="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <!-- 文件上传区域 -->
        <div class="bg-white rounded-lg shadow-sm p-6 fade-in">
            <h2 class="text-xl font-semibold text-gray-700 mb-4">
                <i class="fas fa-cloud-upload-alt mr-2"></i>
                文件上传
            </h2>

            <form id="uploadForm" class="space-y-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">
                        选择文件
                    </label>
                    <input type="file" id="fileInput"
                           class="block w-full text-sm text-gray-500
                       file:mr-4 file:py-2 file:px-4
                       file:rounded-full file:border-0
                       file:text-sm file:font-semibold
                       file:bg-blue-50 file:text-blue-700
                       hover:file:bg-blue-100">
                </div>

                <div>
                    <label class="block text-sm font-medium text-gray-700 mb-2">
                        上传ID
                    </label>
                    <input type="text" id="uploadId"
                           class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                           placeholder="输入唯一标识符" value="upload_">
                </div>

                <button type="submit"
                        class="w-full bg-blue-500 text-white py-2 px-4 rounded-md hover:bg-blue-600 transition-colors">
                    <i class="fas fa-upload mr-2"></i>
                    开始上传
                </button>
            </form>

            <!-- 进度显示区域 -->
            <div class="bg-white rounded-lg shadow-sm p-6 fade-in">
                <h2 class="text-xl font-semibold text-gray-700 mb-4">
                    <i class="fas fa-chart-line mr-2"></i>
                    上传进度
                </h2>

                <div id="progressContainer" class="space-y-4 hidden">
                    <!-- 进度条 -->
                    <div class="space-y-2">
                        <div class="flex justify-between text-sm text-gray-600">
                            <span>上传进度</span>
                            <span id="progressText">0%</span>
                        </div>
                        <div class="w-full bg-gray-200 rounded-full h-4">
                            <div id="progressBar" class="progress-bar bg-blue-500 h-4 rounded-full transition-all duration-300" style="width: 0%"></div>
                        </div>

                        <!-- 状态信息 -->
                        <div id="statusMessage" class="text-sm text-gray-600 p-3 bg-gray-50 rounded-md">
                            等待上传...
                        </div>

                        <!-- 文件信息 -->
                        <div id="fileInfo" class="text-sm text-gray-500 hidden">
                            <div class="flex items-center space-x-2">
                                <i class="fas fa-info-circle text-blue-500"></i>
                                <span id="fileName"></span>
                            </div>
                        </div>
                    </div>
    </main>

    <!-- 状态显示区域 -->
    <div class="mt-6 bg-white rounded-lg shadow-sm p-6 fade-in">
        <h3 class="text-lg font-semibold text-gray-700 mb-3">
            <i class="fas fa-list mr-2"></i>
            上传历史
        </h3>

        <div id="uploadHistory" class="space-y-2">
            <div class="text-gray-500 text-sm">暂无上传记录</div>
        </div>
    </div>

    <script>
        class FileUploadProgress {
            constructor() {
                this.socket = null;
                this.currentUploadId = null;
                this.initializeEventListeners();
            }

            initializeEventListeners() {
                const form = document.getElementById('uploadForm');
                form.addEventListener('submit', (e) => this.handleUpload(e));
            }

            handleUpload(event) {
                event.preventDefault();

                const fileInput = document.getElementById('fileInput');
                const uploadIdInput = document.getElementById('uploadId');
                const file = fileInput.files[0];
                const uploadId = uploadIdInput.value + Date.now();

                if (!file) {
                    alert('请选择文件');
                    return;
                }

                this.currentUploadId = uploadId;
                this.connectWebSocket(uploadId);
                this.startUpload(file, uploadId);
            }

            connectWebSocket(uploadId) {
                if (this.socket) {
                    this.socket.close();
                }

                this.socket = new WebSocket(`ws://localhost:18881/ws/upload?uploadId=${uploadId}`);

                this.socket.onopen = () => {
                    console.log('WebSocket连接已建立');
                };

                this.socket.onmessage = (event) => {
                    const data = JSON.parse(event.data);
                    this.handleWebSocketMessage(data);
                };

                this.socket.onclose = () => {
                    console.log('WebSocket连接已关闭');
                };

                this.socket.onerror = (error) => {
                    console.error('WebSocket错误:', error);
                };
            }

            startUpload(file, uploadId) {
                const formData = new FormData();
                formData.append('file', file);
                formData.append('uploadId', uploadId);

                // 显示进度容器
                document.getElementById('progressContainer').classList.remove('hidden');
                document.getElementById('fileInfo').classList.remove('hidden');

                // 更新文件信息
                document.getElementById('fileName').textContent = `文件名: ${file.name} | 大小: ${(file.size / 1024 / 1024).toFixed(2)} MB`;

                // 发送上传请求
                fetch('http://localhost:18881/v1/websocket/upload', {
                    method: 'POST',
                    body: formData
                }).then(response => response.text())
                    .then(result => {
                        console.log('上传开始:', result);
                    }).catch(error => {
                    console.error('上传错误:', error);
                    this.updateStatus('上传失败', 'error');
                });
            }

            handleWebSocketMessage(data) {
                switch(data.type) {
                    case 'connected':
                        this.updateStatus('连接成功，准备上传', 'info');
                        break;
                    case 'progress':
                        this.updateProgress(data.progress, data.message);
                        break;
                    case 'error':
                        this.updateStatus(data.message, 'error');
                        break;
                }
            }

            updateProgress(progress, message) {
                const progressBar = document.getElementById('progressBar');
                const progressText = document.getElementById('progressText');
                const statusMessage = document.getElementById('statusMessage');

                // 更新进度条
                progressBar.style.width = `${progress}%`;
                progressText.textContent = `${progress}%`;

                // 更新状态信息
                statusMessage.textContent = message;
                statusMessage.className = `text-sm p-3 rounded-md ${
                    progress < 100 ? 'bg-blue-50 text-blue-700' :
                        'bg-green-50 text-green-700'
                }`;

                // 如果上传完成，添加到历史记录
                if (progress === 100) {
                    this.addToHistory(this.currentUploadId, message);
                }
            }

            updateStatus(message, type = 'info') {
                const statusMessage = document.getElementById('statusMessage');
                const colors = {
                    info: 'bg-blue-50 text-blue-700',
                    error: 'bg-red-50 text-red-700',
                    success: 'bg-green-50 text-green-700'
                };

                statusMessage.textContent = message;
                statusMessage.className = `text-sm p-3 rounded-md ${colors[type]}`;
            }

            addToHistory(uploadId, status) {
                const historyContainer = document.getElementById('uploadHistory');

                // 移除"暂无上传记录"提示
                if (historyContainer.querySelector('.text-gray-500')) {
                    historyContainer.innerHTML = '';
                }

                const historyItem = document.createElement('div');
                historyItem.className = 'flex justify-between items-center p-2 bg-gray-50 rounded';
                historyItem.innerHTML = `
                    <span class="text-sm text-gray-700">${uploadId}</span>
                    <span class="text-sm ${status.includes('完成') ? 'text-green-600' : 'text-blue-600'}">
                    ${status}
                </span>
                `;

                historyContainer.insertBefore(historyItem, historyContainer.firstChild);
            }
        }

        // 初始化应用
        document.addEventListener('DOMContentLoaded', () => {
            new FileUploadProgress();
        });
    </script>
</body>
</html>
